#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WMS Simple 打包脚本
使用PyInstaller将项目打包成独立的exe文件
"""

import os
import sys
import shutil
import subprocess
from pathlib import Path

# 项目根目录
project_root = Path(__file__).parent.parent
os.chdir(project_root)

def install_pyinstaller():
    """安装PyInstaller"""
    print("检查PyInstaller...")
    try:
        import PyInstaller
        print("✅ PyInstaller已安装")
        return True
    except ImportError:
        print("正在安装PyInstaller...")
        try:
            subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True)
            print("✅ PyInstaller安装成功")
            return True
        except subprocess.CalledProcessError:
            print("❌ PyInstaller安装失败")
            return False

def create_spec_file():
    """创建PyInstaller规格文件"""
    spec_content = '''# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

# 主程序分析
main_a = Analysis(
    ['main_new.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('config', 'config'),
        ('data', 'data'),
        ('docs', 'docs'),
    ],
    hiddenimports=[
        'uvicorn.lifespan.on',
        'uvicorn.lifespan.off',
        'uvicorn.protocols.websockets.auto',
        'uvicorn.protocols.http.auto',
        'uvicorn.protocols.websockets.websockets_impl',
        'uvicorn.protocols.http.httptools_impl',
        'uvicorn.protocols.http.h11_impl',
        'uvicorn.logging',
        'sqlalchemy.dialects.sqlite',
        'win32timezone',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

# 服务程序分析
service_a = Analysis(
    ['wms_service.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('config', 'config'),
        ('data', 'data'),
    ],
    hiddenimports=[
        'uvicorn.lifespan.on',
        'uvicorn.lifespan.off',
        'uvicorn.protocols.websockets.auto',
        'uvicorn.protocols.http.auto',
        'uvicorn.protocols.websockets.websockets_impl',
        'uvicorn.protocols.http.httptools_impl',
        'uvicorn.protocols.http.h11_impl',
        'uvicorn.logging',
        'sqlalchemy.dialects.sqlite',
        'win32timezone',
        'win32serviceutil',
        'win32service',
        'win32event',
        'servicemanager',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

# 服务配置工具分析
config_a = Analysis(
    ['tools/service_config_manager.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('config', 'config'),
    ],
    hiddenimports=[
        'win32serviceutil',
        'win32service',
        'win32event',
        'servicemanager',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

# 合并分析结果
MERGE((main_a, 'main_new', 'main_new'),
      (service_a, 'wms_service', 'wms_service'),
      (config_a, 'service_config_manager', 'service_config_manager'))

# 主程序PYZ
main_pyz = PYZ(main_a.pure, main_a.zipped_data, cipher=block_cipher)

# 主程序EXE
main_exe = EXE(
    main_pyz,
    main_a.scripts,
    [],
    exclude_binaries=True,
    name='wms_simple',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='docs/icon.ico' if Path('docs/icon.ico').exists() else None,
)

# 服务程序PYZ
service_pyz = PYZ(service_a.pure, service_a.zipped_data, cipher=block_cipher)

# 服务程序EXE
service_exe = EXE(
    service_pyz,
    service_a.scripts,
    [],
    exclude_binaries=True,
    name='wms_service',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

# 配置工具PYZ
config_pyz = PYZ(config_a.pure, config_a.zipped_data, cipher=block_cipher)

# 配置工具EXE
config_exe = EXE(
    config_pyz,
    config_a.scripts,
    [],
    exclude_binaries=True,
    name='service_config_manager',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=False,  # GUI程序，不显示控制台
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

# 收集所有文件
coll = COLLECT(
    main_exe,
    main_a.binaries,
    main_a.zipfiles,
    main_a.datas,
    service_exe,
    service_a.binaries,
    service_a.zipfiles,
    service_a.datas,
    config_exe,
    config_a.binaries,
    config_a.zipfiles,
    config_a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='wms_simple_dist',
)
'''
    
    with open('wms_simple.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)
    
    print("✅ 规格文件创建成功: wms_simple.spec")

def build_exe():
    """执行打包"""
    print("开始打包...")
    try:
        # 使用spec文件打包
        subprocess.run([
            sys.executable, "-m", "PyInstaller", 
            "--clean", 
            "wms_simple.spec"
        ], check=True)
        
        print("✅ 打包成功！")
        return True
    except subprocess.CalledProcessError as e:
        print(f"❌ 打包失败: {e}")
        return False

def create_deployment_package():
    """创建部署包"""
    print("创建部署包...")
    
    dist_dir = Path("dist/wms_simple_dist")
    deploy_dir = Path("deploy")
    
    if deploy_dir.exists():
        shutil.rmtree(deploy_dir)
    
    # 复制打包结果
    shutil.copytree(dist_dir, deploy_dir)
    
    # 创建启动脚本
    start_script = deploy_dir / "启动WMS系统.bat"
    with open(start_script, 'w', encoding='gbk') as f:
        f.write('''@echo off
chcp 65001 > nul
echo ========================================
echo WMS Simple 料位管理系统
echo ========================================
echo 正在启动系统...
wms_simple.exe
pause
''')
    
    # 创建服务管理脚本
    service_script = deploy_dir / "服务管理工具.bat"
    with open(service_script, 'w', encoding='gbk') as f:
        f.write('''@echo off
chcp 65001 > nul
echo ========================================
echo WMS Simple 服务管理工具
echo ========================================
echo 正在启动服务管理工具...
service_config_manager.exe
pause
''')
    
    # 创建部署说明
    readme = deploy_dir / "部署说明.txt"
    with open(readme, 'w', encoding='utf-8') as f:
        f.write('''WMS Simple 料位管理系统 - 部署说明

文件说明：
- wms_simple.exe: 主程序
- wms_service.exe: Windows服务程序
- service_config_manager.exe: 服务配置管理工具
- 启动WMS系统.bat: 快速启动主程序
- 服务管理工具.bat: 快速启动服务管理工具

部署步骤：
1. 将整个文件夹复制到目标服务器
2. 双击"服务管理工具.bat"打开服务管理界面
3. 在服务管理界面中点击"安装服务"
4. 安装成功后可以启动服务，实现开机自启

注意事项：
- 首次安装服务需要管理员权限
- 服务安装后会自动使用打包的exe文件
- 无需安装Python环境，所有依赖已打包
''')
    
    print(f"✅ 部署包创建成功: {deploy_dir}")

def main():
    """主函数"""
    print("========================================")
    print("WMS Simple 打包工具")
    print("========================================")
    print()
    
    # 检查并安装PyInstaller
    if not install_pyinstaller():
        return
    
    # 创建规格文件
    create_spec_file()
    
    # 执行打包
    if not build_exe():
        return
    
    # 创建部署包
    create_deployment_package()
    
    print()
    print("🎉 打包完成！")
    print("部署包位置: deploy/")
    print("可以将deploy文件夹整个复制到目标服务器进行部署")

if __name__ == "__main__":
    main() 